package com.feixiang.springbootinit.strategy;
import cn.hutool.json.JSONUtil;
import com.feixiang.springbootinit.common.ErrorCode;
import com.feixiang.springbootinit.exception.BusinessException;
import com.feixiang.springbootinit.model.entity.wechat.QwFileMessage;
import com.feixiang.springbootinit.model.entity.wechat.QwMessage;
import com.feixiang.springbootinit.model.entity.wechat.QwVoiceMessage;
import com.feixiang.springbootinit.model.enums.SessionArchiveMsgTypeEnum;
import com.feixiang.springbootinit.model.vo.wechat.MsgVO;
import com.feixiang.springbootinit.processor.SessionArchiveBatchProcessor;
import com.feixiang.springbootinit.processor.SessionArchiveProcessor;
import com.feixiang.springbootinit.service.QwFileMessageService;
import com.feixiang.springbootinit.service.FileStorageService;
import com.feixiang.springbootinit.utils.BatchSaveUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
/**
 * 文件消息处理策略
 */
public class FileMessageStrategy implements MessageProcessingStrategy {

    @Autowired
    private QwFileMessageService fileMessageService;

    @Autowired
    private FileStorageService fileStorageService;

    @Override
    public boolean supports(SessionArchiveMsgTypeEnum msgType) {
        return SessionArchiveMsgTypeEnum.FILE == msgType;
    }

    @Override
    public void process(MsgVO msgVO, QwMessage baseMessage) {
        try {

            // 直接使用全局SDK实例（需确保线程安全）
            long sdk = SessionArchiveProcessor.getGlobalSdkInstance();
            // 调用文件存储服务
            log.info("处理文件消息");
            log.info("存储文件: {}", msgVO.getFile().getFilename());
            String storedPath = fileStorageService.storeFile(
                    sdk,
                    msgVO.getFile().getSdkfileid(),
                    msgVO.getFile().getMd5sum(),
                    msgVO.getFile().getFileext(), // 文件扩展名
                    "file" // 子目录
            );
            // 获取访问URL并保存到数据库
            String mediaUrl = fileStorageService.getFileUrl(storedPath);
            QwFileMessage fileMessage = new QwFileMessage();
            fileMessage.setMsgId(msgVO.getMsgid());
            fileMessage.setMediaUrl(mediaUrl);
            fileMessage.setFileSize(msgVO.getFile().getFilesize());
            fileMessage.setFileName(msgVO.getFile().getFilename());
            fileMessage.setFileExt(msgVO.getFile().getFileext());
            fileMessage.setCreatedTime(new Date());
            fileMessageService.save(fileMessage);
        } catch (Exception e) {
            log.error("处理文件消息失败", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "处理文件消息失败");
        }
    }

    @Override
    public void batchProcess(List<QwMessage> baseMessages) {
        if (baseMessages.isEmpty()) {
            log.info("批量处理文件消息: 空列表，无需处理");
            return;
        }
        log.info("开始批量处理文件消息，数量: {}", baseMessages.size());
        long sdk = SessionArchiveBatchProcessor.getGlobalSdkInstance();
        List<QwFileMessage> fileMessages = new ArrayList<>(baseMessages.size());
        Date currentTime = new Date();
        for (QwMessage baseMsg : baseMessages) {
            try {
                // 从基础消息中解析出原始消息对象
                MsgVO msgVO = JSONUtil.toBean(baseMsg.getContent(), MsgVO.class);
                if (msgVO.getFile() == null) {
                    log.warn("文件消息内容为空，msgId: {}", baseMsg.getMsgId());
                    continue;
                }
                // 存储文件
                String storedPath = fileStorageService.storeFile(
                        sdk,
                        msgVO.getFile().getSdkfileid(),
                        msgVO.getFile().getMd5sum(),
                        msgVO.getFile().getFileext(),
                        "file"
                );
                // 构建文件消息实体
                QwFileMessage fileMsg = new QwFileMessage();
                fileMsg.setMsgId(msgVO.getMsgid());
                fileMsg.setMediaUrl(fileStorageService.getFileUrl(storedPath));
                fileMsg.setFileSize(msgVO.getFile().getFilesize());
                fileMsg.setFileName(msgVO.getFile().getFilename());
                fileMsg.setFileExt(msgVO.getFile().getFileext());
                fileMsg.setCreatedTime(currentTime);
                fileMessages.add(fileMsg);
            } catch (Exception e) {
                log.error("批量处理单条文件消息失败, msgId: {}", baseMsg.getMsgId(), e);
                // 单条失败不影响整体批次，继续处理其他消息
            }
            // 批量保存到数据库
            BatchSaveUtil.batchSave(fileMessages, fileMessageService::insertBatch, "文件消息");
//            if (!fileMessages.isEmpty()) {
//                try {
//                    // 分批次保存，每批最多500条
//                    int batchSize = 500;
//                    for (int i = 0; i < fileMessages.size(); i += batchSize) {
//                        int end = Math.min(i + batchSize, fileMessages.size());
//                        List<QwFileMessage> subList = fileMessages.subList(i, end);
//                        fileMessageService.insertBatch(subList);
//                        log.info("已保存文件消息批次: {}-{}, 数量: {}", i, end - 1, subList.size());
//                    }
//                    log.info("批量处理文件消息完成，成功保存: {}", fileMessages.size());
//                } catch (Exception e) {
//                    log.error("批量保存文件消息失败", e);
//                    throw new BusinessException(ErrorCode.OPERATION_ERROR, "批量保存文件消息失败");
//                }
//            }
        }
    }
}